
#include <cmath>
#include "geo_helper.h"
#include "erp/gis/comm/erp_gis_define.h"
#include "c2cent/library/log/CWTimeElf3.h"

using namespace library::geo;
using namespace erp::gis::comm;

static const double DEFAULT_LEVEL1_DISTANCE = 500;   // 地图间相似点距离500米
static const double DEFAULT_LEVEL2_DISTANCE = 2000;  // 地图间相似点距离2000米
static const double DEFAULT_LEVEL3_DISTANCE = 3000;  // 地图最短,第二短距离平均3000米
static const double DEFAULT_LEVEL4_DISTANCE = 1000;  // 仅2点满足条件且最短距离1000
static const double DEFAULT_LEVEL5_DISTANCE = 2000;  // 满足条件最短距离2000米
static const double PI_180  = PI / 180.0;
static const double XPI_180 = 3000.0 * PI_180; 

static const uint32_t MAX_COORDINATES_EACH_MAP = 5;    // 每个地图，最多选择5个经纬度


double CGeoConfig::m_dbDistanceLevel1 = DEFAULT_LEVEL1_DISTANCE;
double CGeoConfig::m_dbDistanceLevel2 = DEFAULT_LEVEL2_DISTANCE;
double CGeoConfig::m_dbDistanceLevel3 = DEFAULT_LEVEL3_DISTANCE;
double CGeoConfig::m_dbDistanceLevel4 = DEFAULT_LEVEL4_DISTANCE;
double CGeoConfig::m_dbDistanceLevel5 = DEFAULT_LEVEL5_DISTANCE;



CGeoCoordinate::CGeoCoordinate()
{
	m_dbX = 0;
	m_dbY = 0;
}

CGeoCoordinate::CGeoCoordinate(double dbX, double dbY)
{
	m_dbX = dbX;
	m_dbY = dbY;
}

void CGeoCoordinate::SetX(double dbX)
{
	m_dbX = dbX;
}
void CGeoCoordinate::SetY(double dbY)
{
	m_dbY = dbY;
}
void CGeoCoordinate::SetXY(double dbX, double dbY)
{
	m_dbX = dbX;
	m_dbY = dbY;
}

double CGeoCoordinate::GetX() const
{
	return m_dbX;
}

double CGeoCoordinate::GetY() const
{
	return m_dbY;
}

void CGeoConfig::SetThreshold4TrustLevel(
			double dbDistanceLevel1,
			double dbDistanceLevel2,
			double dbDistanceLevel3,
			double dbDistanceLevel4,
			double dbDistanceLevel5)
{
	m_dbDistanceLevel1 = dbDistanceLevel1;
	m_dbDistanceLevel2 = dbDistanceLevel2;
	m_dbDistanceLevel3 = dbDistanceLevel3;
	m_dbDistanceLevel4 = dbDistanceLevel4;
	m_dbDistanceLevel5 = dbDistanceLevel5;
}

double CGeoConfig::GetLevel1Threshold()
{
	if (m_dbDistanceLevel1 != 0)
	{
		return m_dbDistanceLevel1;
	}

	return DEFAULT_LEVEL1_DISTANCE;
}
double CGeoConfig::GetLevel2Threshold()
{
	if (m_dbDistanceLevel2 != 0)
	{
		return m_dbDistanceLevel2;
	}

	return DEFAULT_LEVEL2_DISTANCE;
}
double CGeoConfig::GetLevel3Threshold()
{
	if (m_dbDistanceLevel3 != 0)
	{
		return m_dbDistanceLevel3;
	}

	return DEFAULT_LEVEL3_DISTANCE;
}
double CGeoConfig::GetLevel4Threshold()
{
	if (m_dbDistanceLevel4 != 0)
	{
		return m_dbDistanceLevel4;
	}

	return DEFAULT_LEVEL4_DISTANCE;
}
double CGeoConfig::GetLevel5Threshold()
{
	if (m_dbDistanceLevel5 != 0)
	{
		return m_dbDistanceLevel5;
	}

	return DEFAULT_LEVEL5_DISTANCE;
}

/**
 * 计算两个经纬度间的距离，返回单位米
 */
double CGeoHelper::GetEarthDistance(
				double dbX1,
				double dbY1,
				double dbX2,
				double dbY2)
{
	double dbTmp = 0;

	double dbX1_radius = dbX1 * PI_180;
	double dbY1_radius = dbY1 * PI_180;
	double dbX2_radius = dbX2 * PI_180;
	double dbY2_radius = dbY2 * PI_180;

	double dbX12_distance = dbX1_radius - dbX2_radius;
	double dbY12_distance = dbY1_radius - dbY2_radius;

	double dbX12_sin_pow = pow(sin(dbX12_distance/2.0), 2); // power of sin(a/2)
	double dbY12_sin_pow = pow(sin(dbY12_distance/2.0), 2); // power of sin(b/2)

	double dbY1_cos = cos(dbY1_radius);
	double dbY2_cos = cos(dbY2_radius);

	dbTmp = 2 * EARTH_RADIUS * asin(sqrt(dbY12_sin_pow + dbY1_cos * dbY2_cos * dbX12_sin_pow));
	dbTmp = round(dbTmp * 100000) / 100000;
	dbTmp = dbTmp * 1000;
	return dbTmp;
}

double CGeoHelper::GetEarthDistance(
				const CGeoCoordinate& oCoordinate1,
				const CGeoCoordinate& oCoordinate2)
{
	return GetEarthDistance(oCoordinate1.GetX(),
					oCoordinate1.GetY(),
					oCoordinate2.GetX(),
					oCoordinate2.GetY());
}

/**
 * 根据各地图传入的经纬度，通过计算比较，获取各地图中，获取一个最接近的纬度
 * 算法： 1. 计算各地图间两个经纬度最靠近(最短距离)的经纬度AB{(x11,y11),(x12,y12)}，及对应距离d1，
 * 第二靠近的经纬度CD{(x21,y21), (x22,y22)}及对应距离d2，及AB,CD的平均距离Ad12.
 * 2. 计算由各地图间经纬度组成的三点，最长边最短的三点(相当于每个地图中选取1点，组成的三角形中，选择最小三角形)，
 * 获取对应的经纬度AB，BC，AC， 及响应距离d
 * 根据1，2的结果，及经验值，选择认为的最佳经纬度， 并返回对应的信任级别
 * 注：(根据经验值：步骤1，soso及soso2地图，放在同一组， 步骤2：soso及soso2、gaode地图放在同一组计算
 *
 * mapEarthType2GeoGroup: 地图id对应的经纬度列表
 * oClosestCoordinate   : 返回最佳经纬度
 * dwTrustLevel         : 返回最佳经纬度的信任级别
 */
int CGeoHelper::SelectClosestCoordinate(
				const std::map<uint32_t, GeoGroup >& mapEarthType2GeoGroup,
				CGeoCoordinate& oClosestCoordinate,
				uint32_t& dwTrustLevel)
{
	dwTrustLevel = E_GEO_TRUST_LEVEL_6;
	if (mapEarthType2GeoGroup.empty())
	{
		C2C_WW_LOG("mapEarthType2GeoGroup Size Empty");
		return 0;
	}

	std::vector<GeoGroup> vecGeoGroup2Closest;
	std::vector<GeoGroup> vecGeoGroup3Closest;

	GeoGroup oGroupSoso;
	GeoGroup oGroupSoso_Gaode;
	std::map<uint32_t, GeoGroup >::const_iterator iter = mapEarthType2GeoGroup.begin();
	std::map<uint32_t, GeoGroup >::const_iterator iterEnd = mapEarthType2GeoGroup.end();
	for (; iter != iterEnd; iter++)
	{
		uint32_t dwGisApiEarthType = iter->first;

		uint32_t dwSize = 0;
		GeoGroup oGeoGroupTmp; 
		GeoGroup::const_iterator iterGroup = iter->second.begin();
		GeoGroup::const_iterator iterGroupEnd = iter->second.end();
		for (; iterGroup != iterGroupEnd; iterGroup++)
		{
			if (iterGroup->GetX() == 0.0 && iterGroup->GetY() == 0.0)
			{
				// 经纬度为(0,0)认为为无效经纬度
				continue;
			}

			if (dwSize > MAX_COORDINATES_EACH_MAP)
			{
				// 每个地图只取固定的经纬度数目
				continue;
			}

			if (dwGisApiEarthType == E_GISMAP_API_BAIDU)
			{
				// 百度地图经纬度需转换成标准的经纬度
				CGeoCoordinate oBaiduStandardCoordinate;
				Bd2Gcj(*iterGroup, oBaiduStandardCoordinate);
				oGeoGroupTmp.push_back(oBaiduStandardCoordinate);
			}
			else
			{
				oGeoGroupTmp.push_back(*iterGroup);
			}
			dwSize++;
		}
		
		if (dwGisApiEarthType == E_GISMAP_API_SOSO ||
			dwGisApiEarthType == E_GISMAP_API_SOSO2)
		{
			oGroupSoso.insert(oGroupSoso.begin(), oGeoGroupTmp.begin(), oGeoGroupTmp.end()); 
		}
		else
		{
			vecGeoGroup2Closest.push_back(oGeoGroupTmp);
		}

		if (dwGisApiEarthType == E_GISMAP_API_SOSO ||
			dwGisApiEarthType == E_GISMAP_API_SOSO2 ||
			dwGisApiEarthType == E_GISMAP_API_GAODE)
		{
			oGroupSoso_Gaode.insert(oGroupSoso_Gaode.begin(), oGeoGroupTmp.begin(), oGeoGroupTmp.end()); 
		}
		else
		{
			vecGeoGroup3Closest.push_back(oGeoGroupTmp);
		}
	}
	vecGeoGroup2Closest.insert(vecGeoGroup2Closest.begin(), oGroupSoso);
	vecGeoGroup3Closest.insert(vecGeoGroup3Closest.begin(), oGroupSoso_Gaode);
	

	// 2点间距离
	GeoGroup oTwoShort1stCroup; // 图与图间，距离最短的两点.
	GeoGroup oTwoShort2ndCroup; // 图与图间, 距离第二短的两点.
	double dbTwoShort1stDistance; // 最短距离
	double dbTwoShort2ndDistance; // 第二短距离
	double dbTwoAverageDistance;  // 平均距离

	Select2ClosestCoordinate(
			vecGeoGroup2Closest,
			oTwoShort1stCroup,
			oTwoShort2ndCroup,
			dbTwoShort1stDistance,
			dbTwoShort2ndDistance,
			dbTwoAverageDistance);

	// 3点间距离
	GeoGroup oThreeShortestCroup;  // 图与图间, 最靠近的三点(最小三角形)
	double dbThreeMaxSideDistance; // 三点(三角形)中边长最长的距离
	Select3ClosestCoordinate(
				vecGeoGroup3Closest,
				oThreeShortestCroup,
				dbThreeMaxSideDistance);

	double dbTmp = CGeoConfig::GetLevel3Threshold() / 3;
	double dbLevel3ADistance = CGeoConfig::GetLevel3Threshold();
	double dbLevel3Distance1 = dbLevel3ADistance - dbTmp;
	double dbLevel3Distance2 = dbLevel3ADistance + dbTmp;

	if (dbThreeMaxSideDistance <= CGeoConfig::GetLevel1Threshold() &&
		!oThreeShortestCroup.empty())
	{
		dwTrustLevel = E_GEO_TRUST_LEVEL_1;
		oClosestCoordinate = oThreeShortestCroup[0];
	}
	else if (dbThreeMaxSideDistance <= CGeoConfig::GetLevel2Threshold() &&
		!oThreeShortestCroup.empty())
	{
		dwTrustLevel = E_GEO_TRUST_LEVEL_2;
		oClosestCoordinate = oThreeShortestCroup[0];
	}
	else if (
		dbTwoShort1stDistance <= dbLevel3Distance1 &&
		dbTwoShort1stDistance <= dbLevel3Distance2 &&
		dbTwoAverageDistance <= dbLevel3ADistance &&
		!oTwoShort1stCroup.empty())
	{
		dwTrustLevel = E_GEO_TRUST_LEVEL_3;
		oClosestCoordinate = oTwoShort1stCroup[0];
	}
	else if (
		dbTwoShort1stDistance <= CGeoConfig::GetLevel4Threshold() &&
		oThreeShortestCroup.empty() &&
		!oTwoShort1stCroup.empty())
	{
		dwTrustLevel = E_GEO_TRUST_LEVEL_4;
		oClosestCoordinate = oTwoShort1stCroup[0];
	}
	else if (dbTwoShort1stDistance <= CGeoConfig::GetLevel5Threshold() &&
		!oTwoShort1stCroup.empty())
	{
		dwTrustLevel = E_GEO_TRUST_LEVEL_5;
		oClosestCoordinate = oTwoShort1stCroup[0];
	}
	else if (!oTwoShort1stCroup.empty())
	{
		dwTrustLevel = E_GEO_TRUST_LEVEL_6;
		oClosestCoordinate = oTwoShort1stCroup[0];
	}
	else if (!oThreeShortestCroup.empty())
	{
		dwTrustLevel = E_GEO_TRUST_LEVEL_6;
		oClosestCoordinate = oThreeShortestCroup[0];
	}

	return 0;
}

/*
 * 判断经纬度是否在轨迹范围内(使用半线理论)
 * 理论基础：
 * 判断一个点是否在多边形内，只要从这个点向多边形外做一条射线(随机取极远处的一个点，
 * 以这两点为端点做一条线段即可),那么统计射线和多边形的边的交点个数，如果交点个数是奇数
 * 表明点在多边形内，否则在多边形外
 */
bool CGeoHelper::CheckCoordinateInPolyGon(
				const CGeoCoordinate& oCoordinate,
				const GeoGroup& oPolyGonCoordinates)
{
	uint32_t dwPolyGonSize = oPolyGonCoordinates.size();
	if (dwPolyGonSize < 3)
	{
		// 边数小于3,不构成多边形
		return false;
	}

	int iSum = 0;
	double dbx1,dby1,dbx2,dby2;
	double dbx0 = oCoordinate.GetX();
	double dby0 = oCoordinate.GetY();
	for (uint32_t dwIdx = 0; dwIdx < dwPolyGonSize; dwIdx++)
	{
		dbx1 = oPolyGonCoordinates[dwIdx].GetX();
		dby1 = oPolyGonCoordinates[dwIdx].GetY();
		if (dwIdx == dwPolyGonSize - 1)
		{
			dbx2 = oPolyGonCoordinates[0].GetX();
			dby2 = oPolyGonCoordinates[0].GetY();
		}
		else
		{
			dbx2 = oPolyGonCoordinates[dwIdx+1].GetX();
			dby2 = oPolyGonCoordinates[dwIdx+1].GetY();
		}

		if ((dby0 > dby1 && dby0 < dby2) || (dby0 < dby1 && dby0 < dby2))
		{
			// y在两点之间
			if (fabs(dby1 - dby2) > 0)
			{
				// 直线斜率k = (y1-y2)/(x1-x2)
				double dbx = dbx1 - (dbx1 - dbx2)*(dby1 - dby0)/(dby1 - dby2);
				if (dbx < dbx0)
				{
					// 存在交点在该点的左边(-无穷方向),若为+无穷方向, 则dbx>db0判断为有交点
					iSum++;
				}
			}
		}
	}
	if (iSum%2 != 0)
	{
		// 交点为奇数
		return true;
	}

	return false;
}

/*
 * 计算两组地图组合的2个经纬度间最短及第二短的距离及对应经纬度
 * 如地图A有经纬度位置有两点A0, A1, 地图B有经纬度位置有两点B0, B1, 地图C有经纬度位置C
 * 函数计算地图A,B,C经纬度位置间组合:A0B0,A0B1,A0C,A1B0,A1B1,A1C间
 * 距离最短及第二短的经纬度.
 */
int CGeoHelper::Select2ClosestCoordinate(
				const std::vector<GeoGroup >& vecGeoGroup,
				GeoGroup& oShort1stCroup,
				GeoGroup& oShort2ndCroup,
				double& dbShort1stDistance,
				double& dbShort2ndDistance,
				double& dbAverageDistance)
{
	dbShort1stDistance = -1;
	dbShort2ndDistance = -1;

	if (vecGeoGroup.empty())
	{
		C2C_WW_LOG("Select2ClosestCoordinate GeoGroup Empty");
		return 0;
	}
	C2C_WW_LOG("Select2ClosestCoordinate Group:%u", (uint32_t)vecGeoGroup.size());

	// 找到最短距离
	CGeoCoordinate oCoor1st_1;
	CGeoCoordinate oCoor1st_2;

	// 找到第二短距离
	CGeoCoordinate oCoor2nd_1;
	CGeoCoordinate oCoor2nd_2;

	// 轮询各地图中的点，计算各地图中的点与另一个地图的点构成直线距离.
	// 记录最短距离及第二短距离的长度及坐标属性
	uint32_t dwGroupSize = vecGeoGroup.size();
	for (uint32_t dwGroup1Idx = 0; dwGroup1Idx < dwGroupSize; dwGroup1Idx++)
	{
		const GeoGroup& oGeoGroup1 = vecGeoGroup[dwGroup1Idx];

		for (uint32_t dwCoor1Idx = 0; dwCoor1Idx < oGeoGroup1.size(); dwCoor1Idx++)
		{
			const CGeoCoordinate& oCoordinate1 = oGeoGroup1[dwCoor1Idx];

			// 轮询第二组, Group1与Group2计算各经纬度长度，并获取最短距离。
			for (uint32_t dwGroup2Idx = dwGroup1Idx+1; dwGroup2Idx < dwGroupSize; dwGroup2Idx++)
			{
				const GeoGroup& oGeoGroup2 = vecGeoGroup[dwGroup2Idx];

				// 轮询第二组中各经纬度
				for (uint32_t dwCoor2Idx = 0; dwCoor2Idx < oGeoGroup2.size(); dwCoor2Idx++)
				{
					const CGeoCoordinate& oCoordinate2 = oGeoGroup2[dwCoor2Idx];
					double dbDistance = GetEarthDistance(oCoordinate1, oCoordinate2);

					C2C_WW_LOG("Cmp:[x:%f, y:%f]<-->[x:%f, y:%f] distance:%f short1st:%f short2nd:%f",
						oCoordinate1.GetX(), oCoordinate1.GetY(), oCoordinate2.GetX(), oCoordinate2.GetY(),
						dbDistance, dbShort1stDistance, dbShort2ndDistance);

					// 计算最短、第二短距离
					if (dbShort1stDistance < 0 || dbShort1stDistance > dbDistance)
					{
						// 当前经纬度为最短距离中的点
						dbShort2ndDistance = dbShort1stDistance;
						dbShort1stDistance = dbDistance;

						oCoor2nd_1 = oCoor1st_1;
						oCoor2nd_2 = oCoor1st_2;

						oCoor1st_1 = oCoordinate1;
						oCoor1st_2 = oCoordinate2;
					}
					if ((dbShort2ndDistance < 0  || dbShort2ndDistance > dbDistance) && dbShort1stDistance < dbDistance)
					{
						// 当前经纬度为第二短距离中的点
						dbShort2ndDistance = dbDistance;

						oCoor2nd_1 = oCoordinate1;
						oCoor2nd_2 = oCoordinate2;
					}
				}
			}
		}
	}


	if (dbShort1stDistance >= 0)
	{
		dbAverageDistance = dbShort1stDistance;

		oShort1stCroup.push_back(oCoor1st_1);
		oShort1stCroup.push_back(oCoor1st_2);
	}

	if (dbShort2ndDistance >= 0)
	{
		double dbAvg_X1 = (oCoor1st_1.GetX() + oCoor1st_2.GetX()) / 2;
		double dbAvg_Y1 = (oCoor1st_1.GetY() + oCoor1st_2.GetY()) / 2;
		double dbAvg_X2 = (oCoor2nd_1.GetX() + oCoor2nd_2.GetX()) / 2;
		double dbAvg_Y2 = (oCoor2nd_1.GetY() + oCoor2nd_2.GetY()) / 2;
		
		dbAverageDistance = GetEarthDistance(dbAvg_X1, dbAvg_Y1, dbAvg_X2, dbAvg_Y2);
		oShort2ndCroup.push_back(oCoor2nd_1);
		oShort2ndCroup.push_back(oCoor2nd_2);
	}

	C2C_WW_LOG("coor1st_1:[%f,%f] coor1st_2:[%f,%f] coor2nd_1:[%f,%f] coor2nd_2:[%f,%f] "
		"Short1stDistance:%f Short2ndDistance:%f AverageDistance:%f", 
		oCoor1st_1.GetX(), oCoor1st_1.GetY(), oCoor1st_2.GetX(), oCoor1st_2.GetY(), 
		oCoor2nd_1.GetX(), oCoor2nd_1.GetY(), oCoor2nd_2.GetX(), oCoor2nd_2.GetY(), 
		dbShort1stDistance, dbShort2ndDistance, dbAverageDistance);

	return 0;
}

/*
 * 计算各组地图间最相似的三个经纬度(点)
 * 原理:假如地图A有经纬度位置A0,A1两个点, 地图B有经纬度位置B0,B1两个点,地图C有经纬度C
 * 则计算三角形D0:A0-B0-C,三角形D1: A0-B1-C,三角形D2:A1-B0-C,三角形D3:A1-B1-C中的
 * 最长边, 认为最长边最短的三角形各点最靠近(相似)。
 */
int CGeoHelper::Select3ClosestCoordinate(
				const std::vector<GeoGroup >& vecGeoGroup,
				GeoGroup& oShortestCroup,
				double& dbMaxSideDistance)
{
	dbMaxSideDistance = -1; // 最小三角形中最长边的长度

	// 三角形中三个点
	CGeoCoordinate oCoordinate1;
	CGeoCoordinate oCoordinate2;
	CGeoCoordinate oCoordinate3;

	uint32_t dwGeoGroupSize = vecGeoGroup.size();

	// 轮询各地图中的点，每个地图中选择1点，构成三角形，并计算最长边
	for (uint32_t dwGroup1Idx = 0; dwGroup1Idx < dwGeoGroupSize; dwGroup1Idx++)
	{
		for (uint32_t dwGroup2Idx = dwGroup1Idx+1; dwGroup2Idx < dwGeoGroupSize; dwGroup2Idx++)
		{
			for (uint32_t dwGroup3Idx = dwGroup2Idx+1; dwGroup3Idx < dwGeoGroupSize; dwGroup3Idx++)
			{
				// 选择的三张地图中寻找最长边最小的三角形.
				const GeoGroup& oGeoGroup1 = vecGeoGroup[dwGroup1Idx];
				const GeoGroup& oGeoGroup2 = vecGeoGroup[dwGroup2Idx];
				const GeoGroup& oGeoGroup3 = vecGeoGroup[dwGroup3Idx];
				for (uint32_t dwCoor1Idx = 0; dwCoor1Idx < oGeoGroup1.size(); dwCoor1Idx++)
				{
					for (uint32_t dwCoor2Idx = 0; dwCoor2Idx < oGeoGroup2.size(); dwCoor2Idx++)
					{
						for (uint32_t dwCoor3Idx = 0; dwCoor3Idx < oGeoGroup3.size(); dwCoor3Idx++)
						{
							const CGeoCoordinate& oCoorTemp1 = oGeoGroup1[dwCoor1Idx];
							const CGeoCoordinate& oCoorTemp2 = oGeoGroup2[dwCoor2Idx];
							const CGeoCoordinate& oCoorTemp3 = oGeoGroup3[dwCoor3Idx];

							double dbDist0 = GetEarthDistance(oCoorTemp1, oCoorTemp2);
							double dbDist1 = GetEarthDistance(oCoorTemp1, oCoorTemp3);
							double dbDist2 = GetEarthDistance(oCoorTemp2, oCoorTemp3);

							double dbMaxSideDistTmp = (dbDist0 > dbDist1) ?
								std::max(dbDist0, dbDist2) : std::max(dbDist1, dbDist2);

							C2C_WW_LOG_DEBUG("maxsidedist:%f maxsidedisttemp:%f", dbMaxSideDistance, dbMaxSideDistTmp);

							if (dbMaxSideDistance < 0 || dbMaxSideDistTmp < dbMaxSideDistance)
							{
								dbMaxSideDistance = dbMaxSideDistTmp;

								oCoordinate1 = oCoorTemp1;
								oCoordinate2 = oCoorTemp2;
								oCoordinate3 = oCoorTemp3;
							}
						}
					}
				}
			}
		}
	}

	if (dbMaxSideDistance >= 0)
	{
		oShortestCroup.push_back(oCoordinate1);
		oShortestCroup.push_back(oCoordinate2);
		oShortestCroup.push_back(oCoordinate3);
	}

	C2C_WW_LOG("coor1:[%f, %f] coor2:[%f, %f] coor3:[%f, %f] distance:%f",
		oCoordinate1.GetX(), oCoordinate1.GetY(), oCoordinate2.GetX(), oCoordinate2.GetY(),
		oCoordinate3.GetX(), oCoordinate3.GetY(), dbMaxSideDistance);

	return 0;
}

/*
 * 将百度经纬度转为通用经纬度
 */
void CGeoHelper::Bd2Gcj(
				const CGeoCoordinate& oBdCustormCoordinate,
				CGeoCoordinate& oBdStandardCoordinate)
{
	
	double x = oBdCustormCoordinate.GetX()- 0.0065;
	double y = oBdCustormCoordinate.GetY() - 0.006;
    double z = sqrt(x * x + y * y) - 0.00002 * sin(y * XPI_180);
    double theta = atan2(y, x) - 0.000003 * cos(x * XPI_180);

	oBdStandardCoordinate.SetX(z * cos(theta));
    oBdStandardCoordinate.SetY(z * sin(theta));
}

